package gameUtils;
import gameExceptions.*;

public class LinearList {
	public LinearListNode front;
	public LinearListNode rear;
	public int size;
	
	public void addEntity(LinearListNode node){
		if(size == 0){
			front = node;
			rear = node;
			size++;
		}else{
			rear.nextNode = node;
			this.rear = rear.nextNode;
			size ++;
		}
	}
	public void canShove(int number) throws NonShoveableSectionException{
		if((size < 2) || (number >= size-1)){
			throw new NonShoveableSectionException();
		}
	}
	public void shoveEntity(LinearListNode node, int previous){
		
		try{
		System.out.println("Begin Shoving entity");
		LinearListNode temp = find(previous);
		canShove(previous);
		System.out.println(temp.toString());
		LinearListNode tempNext = temp.nextNode;
		System.out.println(tempNext.toString());
		temp.nextNode = node;
		node.previousNode = temp;
		tempNext.previousNode = node;
		node.nextNode = tempNext;
		size++;
		System.out.println("End Shoving entity");
		}catch(ListIndexOutOfBoundsException $e){
			System.out.println("Entered integer: "+previous+" List Range: 0 to "+(size-1));
			System.err.println("ListIndexOutOfBoundsException"+ $e.getMessage());
		}catch(NonShoveableSectionException $e){
			System.out.println("Entered integer: "+previous);
			System.out.println();
			System.err.println("NonShoveableSectionException"+ $e.getMessage());
		}
		
		
	}
	public void prependEntity(LinearListNode node){
		node.nextNode = front;
		front.previousNode = node;
		front = node;
		size++;
	}
	public LinearListNode find(int find) throws ListIndexOutOfBoundsException{
		if((find >= size) || (find <0)){
			throw new ListIndexOutOfBoundsException();
		}
		LinearListNode temp = this.front;
		int count = 0;
		
		while(count != find){
			temp = temp.nextNode;
			count++;
		}
		return temp;
	}
	
	public void cutEntityFront(){
		if(!this.isEmpty() && size >1){
		front = front.nextNode;
		front.previousNode = null;
		size--;
		}else{
			System.out.println("The list isn't big enough to cut an entity off from it");
		}
	}
	public void cutEntityRear(){
		if(!this.isEmpty() && size >1){
		rear = rear.previousNode;
		rear.nextNode = null;
		size--;
		}else{
			System.out.println("The list isn't big enough to cut an entity off from it");
		}
	}
	public void removeEntity(int location) {
		try{
		LinearListNode temp = find(location);
		LinearListNode tempPrev = temp.previousNode;
		LinearListNode tempNext = temp.nextNode;
		tempPrev.nextNode = tempNext;
		tempNext.previousNode = tempPrev;
		temp.nextNode = null;
		temp.previousNode = null;
		size--;
		}catch(ListIndexOutOfBoundsException $e){
			System.out.println("Entered integer: "+location);
			System.err.println("ListIndexOutOfBoundsException"+ $e.getMessage());
		}
	}
	public void clearList(){
		front = null;
		rear = null;
		size = 0;
	}
	public void swapEntities(int nodeA, int nodeB){
		if(nodeA != nodeB){
			Object temp;
			try{
				LinearListNode tempA = find(nodeA);
				LinearListNode tempB = find(nodeB);
				temp = tempA.nodeContents;
				tempA.nodeContents = tempB.nodeContents;
				tempB.nodeContents = temp;
			}catch(ListIndexOutOfBoundsException $e){
				System.out.println("Node A Location: "+nodeA+" Node B Location: "+nodeB);
				System.err.println("ListIndexOutOfBoundsException"+$e.getMessage());
			}
		}else{
			System.out.println("The Items being Switched are the Same");
		}
		
	}
	
	public boolean isEmpty(){
		return (front == null)?true:false ; 
		}
	public String toString(){
		if(!this.isEmpty()){
			String toString = new String("[ ");
			LinearListNode temp = front;
			for(int i = 0; i < size-1; i++){
				toString = toString.concat(temp.nodeContents.toString() + ", ");
				temp = temp.nextNode;
			}
			toString = toString.concat(rear.nodeContents.toString()+ " ]");
			return toString;
		}else{
			return "The List is Empty";
		}
	}
	public LinearList (){
		front = null;
		rear = null;
		size = 0;
	}
}
